#ifndef __DUPLA_H__
#define __DUPLA_H__

#include <iostream>
#include <cassert>
using namespace std;

template<class T, class U>

struct Dupla {
	/**
	 * Constructor.
	 * Utilizado para permitir inicializaciones sin parámetros.
	 */
	Dupla();

	/**
	 * Constructor.
	 * Toma un parámetro de tipo T y uno de tipo U
	 * y crea una dupla con los parámetros pasados.
	 *
	 * @var T a
	 * @var U b
	 */
	Dupla(const T& a,const U& b);

	/** constructor por copia */
	Dupla(const Dupla<T,U>&);

	/** operador asignacion */
	Dupla<T,U> operator=(const Dupla<T,U>&);

	/**
	 * Operador "=="
	 */
	bool operator==(const Dupla<T,U>&) const;

	/**
	 * Operador "!="
	 */
	bool operator!=(const Dupla<T,U>&) const;

	T fila;
	U columna;
};


template<class T, class U>
Dupla<T,U>::Dupla(){}

template<class T, class U>
Dupla<T,U>::Dupla(const T& a,const U& b) {
	fila = a;
	columna = b;
}

template<class T, class U>
ostream& operator<<(ostream& out, const Dupla<T,U>& l) {
	out<<"("<< l.fila<<"," << l.columna<< ")";
	return out;
}

template<class T, class U>
bool Dupla<T,U>::operator==(const Dupla<T,U>& l) const{
	return (fila==l.fila) && (columna==l.columna);
}

template<class T, class U>
bool Dupla<T,U>::operator!=(const Dupla<T,U>& l) const{
	return ! (*this==l);
}

template<class T, class U>
Dupla<T,U>::Dupla(const Dupla<T,U>& other){
	this->fila = other.fila;
	this->columna = other.columna;
}

template<class T, class U>
Dupla<T,U> Dupla<T,U>::operator=(const Dupla<T,U>& other){
	if(this != &other){
		this->fila = other.fila;
		this->columna = other.columna;
	}
	return *this;
}




#endif
